Скобочная последовательность – это
правильное арифметическое выражение, из которого удалены все числа и знаки
операций. Например,
1 + ( ( ( 2 + 3 ) + 5 ) + ( 3 + 4 ) ) → ( ( ( ) ) ( ) )
Вход. Задана последовательность из
открывающихся и закрывающихся скобок длиной не более 4 * 106.
Выход. Выведите “YES”, если скобочная последовательность правильная,
и “NO” иначе.
Пример
входа 1 |
Пример
выхода 1 |
((())()) |
YES |
|
|
Пример
входа 2 |
Пример
выхода 2 |
(() |
NO |
стек
Объявим стек, в
который будем помещать только открывающиеся скобки. При поступлении очередного
символа выполняем следующую операцию со стеком:
·
если встречается символ ‘(‘, то заносим его в стек;
·
если встречается символ ‘)‘, то извлекаем элемент из
стека. Если при этом стек оказывается пустым, то последовательность не является
скобочной (на некотором этапе количество закрывающихся скобок превышает
количество открывающихся);
По окончании
обработки строки стек должен оставаться пустым.
Моделирование стека
можно осуществить с использованием единственной переменной. Пусть переменная cnt хранит количество открытых скобок в
стеке. Тогда при помещении символа ‘(‘ в стек увеличим cnt на 1, а при извлечении элемента из стека –
уменьшаем cnt на 1.
Пример
Промоделируем
работу стека для строки “((())())” из первого
примера.
Читаем входную строку.
cin >> s;
Переменная cnt хранит
количество текущих незакрытых скобок (то есть количество открывающихся скобок, для
которых еще не встретились соответствующие закрывающиеся скобки).
Переменная flag устанавливается в 1, если на какой-то итерации количество закрывающихся скобок
становится больше числа открывающихся. Изначально установим
flag = 0.
cnt = flag = 0;
Обрабатываем входную строку посимвольно,
моделируя работу со стеком.
for (i = 0; i < s.size(); i++)
{
Обрабатываем текущий символ s[i].
if (s[i] == '(') cnt++; else cnt--;
Если количество закрывающихся скобок
в некоторый момент времени становится больше числа открывающихся, то входная
последовательность не является скобочной.
if (cnt < 0)
flag = 1;
}
В зависимости от значений переменных flag и cnt выводим ответ. Стек будет пустым
в конце обработки строки, если cnt = 0.
if (flag ==
0 && cnt == 0)
cout << "YES\n"; else cout << "NO\n";
Java реализация через строку
import java.util.*;
public class Main
{
public static void
main(String[] args)
{
Scanner con = new
Scanner(System.in);
String s = con.nextLine();
boolean flag = false;
int open = 0;
for(int i = 0;
i < s.length(); i++)
{
if (s.charAt(i) == '(')
open++;
else
open--;
if (open <
0)
flag = true;
}
if (flag || (open >
0))
System.out.println("NO");
else
System.out.println("YES");
con.close();
}
}
Java реализация через массив символов
import java.util.*;
public class Main
{
public static void
main(String[] args)
{
Scanner con = new
Scanner(System.in);
char s[] = con.nextLine().toCharArray();
boolean flag = false;
int open = 0;
for(int i = 0;
i < s.length; i++)
{
if (s[i] == '(')
open++;
else
open--;
if (open <
0)
flag = true;
}
if (flag || (open >
0))
System.out.println("NO");
else
System.out.println("YES");
con.close();
}
}
Python реализация
Читаем входную строку.
s = input()
Переменная cnt хранит
количество текущих незакрытых скобок (то есть количество открывающихся скобок, для
которых еще не встретились соответствующие закрывающиеся скобки).
Переменная flag устанавливается в 1, если на какой-то итерации количество закрывающихся скобок
становится больше числа открывающихся. Изначально установим
flag = 0.
cnt = flag = 0
Обрабатываем входную строку посимвольно,
моделируя работу со стеком.
for ch in s:
Обрабатываем текущий символ s[i].
if ch == '(': cnt += 1
else: cnt -= 1
Если количество закрывающихся скобок
в некоторый момент времени становится больше числа открывающихся, то входная
последовательность не является скобочной.
if cnt < 0: flag = 1
В зависимости от значений переменных flag и cnt выводим ответ. Стек будет пустым
в конце обработки строки, если cnt = 0.
if flag == 0 and cnt == 0:
print("YES")
else:
print("NO")